Amazon ElastiCache(Redis)が2.8.19にアップデート、声に出して読みたい「HyperLogLog」が追加。
こんにちは、せーのです。今日はElastiCacheがアップデートされて新機能が追加されたのでご紹介致します。
HyperLogLog
HyperLogLog。なんてかわいい響きでしょう。はいぱーろぐろぐ。ゆるキャラ、というよりポケモン化して欲しいイメージの言葉です。 HyperLogLogとはCardinalityを推定するデータオブジェクトの事を言います。Cardinalityってなんでしょう。Cardinalityは直訳すると「濃度」となります。ITの世界では「異なり数」とか「多重度」とか言われるもので、「重複しているものを1つとカウントした場合の総カウント数」の事を指します。主にビッグデータ解析や形態素解析などで用いる言葉で、例えば一つの文章中に「天ぷらうどん」という文字が2回、「きつねうどん」という文字が3回出てきた場合、異なり数は2、延べ数が5、となります。HyperLogLogはこの数値を推定するために使うものです。
これを聞いて「何か全然関係ない」と思う方もいるでしょう。私も思いました。これ、どう使うんだと。これをWebシステムに置き換えると、例えばシステムへのユーザーのアクセス状況をカウントしたいとします。ユニークユーザーがどれくらいアクセスし、どのページをどれくらい回っているのか見たい。でもページにアクセスしている人が同じユーザーかどうか、というのを判定するにはCookieを撒いたりセッションを見たりハッシュを作ったり、と結構な実装が必要で、毎回DBへのアクセスも必要になります。あくまでマーケティングに使用するための処理で本サービスに影響をあたえるわけにはいかないですよね。こういう場合にHyperLogLogを大体の主要なページにcreateして、ユーザー名をキーにサクサクaddさせていくと、標準誤差0.81%というかなりの精度でユーザーの訪問状況が推定できます。通常なら毎回の訪問ごとにそれをきちんと記録しないと集計できませんので、ユーザーがアクセスする度に使用メモリが増えていくのがロギングの通常なのですが、HyperLogLogはアルゴリズムを使用して訪問数を推定するのでユーザーのキー毎の訪問回数が増えてもデータ構造はコンパクトなままなので本サービスに影響もほぼありません。
HyperLogLogのコマンド
RedisのHyperLogLogは主に3つのコマンドから成り立ちます。
- PFADD : キーを指定して要素を追加します
- PFCOUNT : それぞれのユニークな要素の現在の近似値を推定します
- PFMERGE : 異なるキーを結合します
実際に見てみると意外と簡単そうですね。ちなみに各コマンドの頭に付いている「PF」という接頭詞はHyperLogLogアルゴリズムを考案したPhilippe Flajoletさんのイニシャルに基づいているそうです。
やってみた
なんとなくわかったので試してみましょう。Management ConsoleからElastiCacheのページに行き、クラスタを新たに立ち上げます。
EngineをRedisに、バージョンを「2.8.19」に設定します。
EC2を立ち上げ、yum updateしRedisを入れます。
[root@ip-172-31-2-254 ~]# yum install -y redis --enablerepo=epel 読み込んだプラグイン:priorities, update-motd, upgrade-helper amzn-main/latest | 2.1 kB 00:00 epel/x86_64/metalink | 5.4 kB 00:00 epel/x86_64 | 4.4 kB 00:00 epel/x86_64/group_gz | 237 kB 00:00 epel/x86_64/updateinfo | 952 kB 00:00 epel/x86_64/primary_db | 6.4 MB 00:00 epel/x86_64/pkgtags | 1.4 MB 00:00 1017 packages excluded due to repository priority protections ......中略...... インストール中 : redis-2.4.10-1.el6.x86_64 1/1 検証中 : redis-2.4.10-1.el6.x86_64 1/1 インストール: redis.x86_64 0:2.4.10-1.el6 完了しました!
そうこうやっているうちにElastiCacheが立ち上がりました。
早速接続してみます。EC2とElastiCacheに対してセキュリティグループを使用して通信ができるように設定しておくのを忘れないように。
[root@ip-172-31-2-254 ~]# redis-cli -h test.yd4jyh.ng.0001.apne1.cache.amazonaws.com redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> info # Server redis_version:2.8.19 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:b718aff3b904214 redis_mode:standalone os:Amazon ElastiCache arch_bits:64 multiplexing_api:epoll gcc_version:0.0.0 process_id:1 run_id:492956f6a72744db3930771dce7c573a8d050fb6 tcp_port:6379 uptime_in_seconds:708 uptime_in_days:0 hz:10 lru_clock:59818 config_file:/etc/redis.conf # Clients connected_clients:6 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 ......後略......
接続を確認しました。バージョンも2.8.19になってますね。でははいぱーろぐろぐを試してみましょう。まずは要素を追加して、数えてみます。
redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFADD hll a b c d e f g (integer) 1 redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFCOUNT hll (integer) 7
[hll]というキーに「a」から「g」まで7つの値を入れたので、Cardinalityは7となります。次に重複する要素を入れてみましょう。
redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFADD hll a a a a a (integer) 0 redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFADD hll b d e a g (integer) 0 redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFCOUNT hll (integer) 7
既に入っている要素は重複となるので追加に対してカウントされていません。次に別のキーで要素を入れてみます。
redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFADD hll2 a a2 a3 (integer) 1 redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFCOUNT hll2 (integer) 3
これも同じように[hll2]というキーに「a」「a2」「a3」という3つの要素を入れたのでCardinalityは3です。次にこの2つのキーをマージしてみます。
redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFMERGE hll hll2 OK redis test.yd4jyh.ng.0001.apne1.cache.amazonaws.com:6379> PFCOUNT hll (integer) 9
キー[hll]にキー[hll2]をマージしました。改めて[hll]の数を数えてみると「a」「b」「c」「d」「e」「f」「g」「a2」「a3」で合計9つ、となります。どうでしょう。簡単ですね。
まとめ
いかがでしたか。HyperLogLog、使ってみるととても簡単ですので是非活用してみてください。 ※ハイパーログログ、という名前のハンバーガー屋さんがあってもいいかもしれません。